package com.hll.erp.controller;

import com.hll.erp.entity.Buy;
import com.hll.erp.entity.Product;
import com.hll.erp.entity.ResultMap;
import com.hll.erp.service.BuyService;
import com.hll.erp.service.CategoryService;
import com.hll.erp.service.ProductService;
import com.hll.erp.util.JsonXMLUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

/**
 * (Buy)表控制层
 *
 * @author makejava
 * @since 2021-07-04 15:17:56
 */
@RestController
@RequestMapping("buy")
@Api(
    value = "Buy Controller",
    tags = {"产品购买接口"})
public class BuyController {
  /** 服务对象 */
  @Autowired private BuyService buyService;

  @Autowired private CategoryService categoryService;
  @Autowired private ProductService productService;

  // 添加这个才能正确接收Date, 且必须按照格式 2021-6-30 12:21:21
  // 少写一部分都不行
  @InitBinder
  public void initBinder(WebDataBinder binder) {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
  }

  @RequiresRoles("buyer")
  @ApiOperation(value = "获取购买记录,分页方式")
  @PostMapping("/getBuys")
  public ResultMap getBuys(
      @RequestParam(defaultValue = "1", value = "pageNo") Integer pageNo,
      @RequestParam(defaultValue = "5", value = "pageSize") Integer pageSize,
      @RequestParam(required = false) Date start,
      @RequestParam(required = false) Date end) {
    return new ResultMap()
        .success()
        .code(200)
        .message(buyService.getBuys(pageNo, pageSize, start, end));
  }

  /*
    其中字段必须齐全，但只有部分字段有效,比如 pname,category, buy中的number,price,comment
    {
      "product": {
          "pid": null,
          "pname": "充电器",
          "category": 1,
          "number": null
      },
      "buy": {
          "id": null,
          "pid": null,
          "buyNumber": 2,
          "buyPrice": 2,
          "buyDate": null,
          "comment":"haha"
      }
  }
    * */
  // 出于某种考量，我决定传两个对象参数尽量,不能用两个@RequestBody，方案一：封装成一个类, 方法二：使用map
  // 如果产品名不存在需要插入产品仓库
  @RequiresRoles("buyer")
  @ApiOperation(value = "添加购买记录")
  @PostMapping("/buyProduct")
  @Transactional
  public ResultMap buyExistedProduct(@RequestBody Map<String, Object> objects) throws Exception {
    Product pro = JsonXMLUtils.map2obj((Map<String, Object>) objects.get("product"), Product.class);
    Buy buy = JsonXMLUtils.map2obj((Map<String, Object>) objects.get("buy"), Buy.class);
    ResultMap resultMap = new ResultMap();
    Product product = productService.getProductByName(pro.getPname());
    if (pro.getPname() == null
        || (product == null && categoryService.getById(pro.getCategory()) == null)
        || buy.getBuyNumber() == null
        || buy.getBuyNumber() <= 0
        || buy.getBuyPrice() == null
        || buy.getBuyPrice() < 0
        || (buy.getComment() != null && buy.getComment().length() > 100))
      return resultMap.fail().code(201).message("参数不正确");
    try {
      boolean flag;
      if (product == null) {
        product = new Product("0", pro.getPname(), pro.getCategory(), buy.getBuyNumber());
        flag = productService.save(product);
        product = productService.getProductByName(product.getPname());
      } else {
        product.setNumber(product.getNumber() + buy.getBuyNumber());
        flag = productService.updateById(product);
      }
      if (flag) {
        buy.setPid(product.getPid());
        buy.setBuyDate(new Date());
        if (buyService.save(buy)) {
          return resultMap.success().code(200).message("采购成功");
        }
      }
    } catch (Exception e) {
      TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    }
    return resultMap.fail().code(201).message("数据库存储失败");
  }

  @PostMapping("/getBuyCount")
  public ResultMap getBuyCount() {
    return new ResultMap().success().code(200).message(buyService.count());
  }
}
